home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Utilities Professional 1-1500
/
Utilities Professional 1-1500 (1994)(WPD)[!].iso
/
12511500
/
var1449.dms
/
var1449.adf
/
GameportDevice
/
GameportDevice.doc
< prev
next >
Wrap
Text File
|
1992-04-27
|
34KB
|
1,060 lines
3 GAMEPORT DEVICE
3.1 INTRODUCTION
All Amiga models have two contacts to which you can connect extra
input devices like a mouse, joystick, trackball, proportional
joystick etc. If Intuition is used, the left gameport is
reserved for a mouse that controls the pointer. However, the
right port can be used freely.
To monitor these two gameports you can uses the Gameport
Device. It is a clean and polite way of controlling the
gameports. You can of course go directly on the hardware
and check what is happening. This is both easier and faster,
but should only be used in games since it is not so polite
to the system.
If you go directly on the hardware your program will be
machine dependent, and may not run on future models of the
Amiga.
I doubt that Commodore ever will try to change the hardware
position of the gameport, but you never know. Programs that
use the Gameport device will on the other hand always work,
even if an Amiga 4000 is released. So if you can use the
Gameport Device instead of hitting the hardware directly,
stick to the device.
3.2 COMMON INPUT DEVICES FOR THE GAMEPORT
To the gameports you can connect several types of input
devices, like: - Mouse
- Joystick
- Proportional (analogue) joystick
- Light pen
- Drawing (Digitizing) tablet
- Trackball
The most commonly used input devices is undoubtedly the mouse and
joystick. However, inputdevices like analogue joysticks, light
pens and digitizing tablets are getting more and more popular.
It is very common that a joystick is already connected to the
right port. Most games expect that, but it does not mean that
you can not connect a second mouse or proportional joystick
there. It is a good rule to always tell the user what type
of input device he/she should use, before your program starts.
3.2.1 MOUSE
The mouse is the most commonly used device since all Amigas are
sold together with one. It is perfect for positioning cursors
(like Intuition's pointer), or to move a gun-sight over some
enemies.
A mouse usually consists of a rubber ball covered by a box
with one or more buttons on top. When the user is sliding the
mouse, the rubber ball is rotated and delta x and y movements
are reported.
The normal Amiga mouse comes with two buttons, but there exist
those with only one or three buttons.
3.2.2 JOYSTICK
A normal joystick (also called absolute joystick) can only
report 8 stick movements like: up, right, down, left and
possible combinations like up and to the right. A joystick
can have one or two buttons. Sadly most joystick comes with only
one button.
3.2.3 PROPORTIONAL JOYSTICK
A proportional (or analog) joystick is like a normal absolute
joystick with one difference, it will report the exact delta
position on the stick. The further in one direction, the higher
number is broadcasted.
Proportional joysticks are perfect for flight simulators and
similar programs. They are becoming more available nowadays,
so it is a good idea to start supporting this type of device.
The Gameport Device can sadly not handle proportional joysticks
for the moment which is a pity. However, I have included a
small program in the "Input" drawer called "Analogue" which
reads proportional (analogue) joystick movements directly from
the hardware registers.
3.2.4 LIGHT PEN
A light pen is a small device with which you can point anywhere
on the screen in order to position a cursor or select an
option. There have during the last years been a big discussion
about which device, a mouse or a light pen, is easiest to use.
I think it depends on what you are going to do. A pen is
undoubtedly more natural for a beginner, but your arm gets very
tired after some minutes, so it should not be used to much.
Luckily you do not need to bother about the light pen since it
is also sadly not supported by the Gameport Device. However,
newly made light pens usually comes with some software that
replaces Intuition's mouse with the light pen. If you write
your program as normal and is monitoring a mouse, the user can
still connected and use a light pen. Your program whould not
notice any difference.
3.2.5 DRAWING (DIGITIZING) TABLET
Drawing (Digitizing) tablet is used in the same manner as a
light pen, but with the advantage that your arm does not get
so tired, and with the disadvantage that all your free space
on your desk is suddenly occupied by a large sensitive tablet.
(It is not recommended to spill hot coffee on it for example.)
Drawing tablets are not either supported by the Gameport
Device. However, as same as with the light pen, most digitizing
tablets comes with some software that replaces the normal
mouse driver with its own driver. So if your program supports
a mouse, it can also handle most digitizing tablets.
3.2.5 TRACKBALL
A trackball is working exactly as a mouse, but with the
advantage that you do not have to move it around. Since it
acts exactly as a mouse you do not have to bother about any
special routines for handling trackballs. Simply support
mouse events and the user can connect a trackball instead.
3.3 THE GAMEPORT DEVICE
The Gameport Device helps you to monitor the Amiga's two
gameports. Port 1 (unit 0) is usually already occupied by
Intuition, but port 2 (unit 1) can normally be used. The
Gameport Device supports for the moment only two types
of input devices, and they are: 1. Mouse (Trackball)
2. Joystick
To prepare the Gameport Device to handle input events you
have to:
1. Create a message port with which the Gameport Device
can communicate with you.
[ CreatePort() ]
2. Allocate an input/output request block (structure).
[ CreateStdIO() ]
3. Open the Gameport Device
[ OpenDevice() ]
4. Check if some other task is already using the gameport.
(A gameport can only be monitored by one task.)
5. Tell the Gameport Device what type of input device you
want to monitor. (For the moment you can only monitor
mouse or joystick events.)
6. Tell the Gameport Device what events should be reported,
and when.
7. Tell the Gameport Device that we want to start collecting
gameport events.
3.3.1 CREATE A MESSAGE PORT
As normal when you are using a device, you first have to create
a message port with which the device can communicate with you.
The simplest way is to create a message port by calling the
CreatePort() function, which will return a pointer to a MsgPort
structure (defined in the headerfile "exec/ports.h").
CreatePort() allocates and initializes a MsgPort structure. If
you give it a string as first parameter it will also make the
port public. If CreatePort() of some reason could not create a
message port it returns NULL, otherwise if everything is OK it
returns a pointer to the new MsgPort structure.
Synopsis: msgp = CreatePort( name, pri );
msgp: (struct MsgPort *) Pointer to the new MsgPort
structure, or NULL if something went wrong.
name: (char *) Pointer to a string containing the name
of the message port, or NULL. If it is a string
the port will be made public (so other tasks can
find it) else only our task can use it.
msgp: (struct MsgPort *) Pointer to the MsgPort structure
that should be allocated.
pri: (BYTE) This message port's priority. Usually set
to 0 - normal priority.
When your program terminates you must close the message port
by calling the DeletePort() function!
DeletePort() deletes a message port. Every message port that
has been allocated by CreatePort() must be deleted before the
program terminates.
Synopsis: DeletePort( msgp );
msgp: (struct MsgPort *) Pointer to the MsgPort structure,
that should be deallocated.
Here is an example:
/* Declare a pointer to our message port: */
struct MsgPort *game_msg_port;
/* Create the message port: */
/* (No name, priority 0.) */
game_msg_port = CreatePort( 0, 0 );
/* Check if we have received a message port or not: */
if( !game_msg_port )
/* ERROR! Could not create message port! */
...
/* Close message port: */
DeletePort( game_msg_port );
3.3.2 ALLOCATE AN INPUT/OUTPUT REQUEST BLOCK (STRUCTURE)
Secondly you need a I/O request structure (IOStdReq) in which
you can store information like where the data is that should
be processed and how much data you send. When the Gameport
Device has replied you can find error message, if any, in the
structure etc. More about this later.
The IOStdReq structure should also be linked together with our
message port. We will then receive a message each time the
Gameport Device returns our I/O request.
The best way to allocate an IOStdReq structure is to call the
CreateStdIO() function which will both allocate and pre-
initialize the structure. (The IOStdReq structure is defined in
the headerfile "exec/io.h".) We give CreateStdIO() a pointer to
our message port, so it will automatically be linked together.
CreateStdIO() allocates and initializes a new IOStdReq
structure. As only parameter you give it a pointer to a message
port that will be used by the system to communicate with you.
If the function succeeds, it returns a pointer to the new
IoStdReq structure, else NULL which means something went wrong.
Synopsis: io = CreateStdIO( msgp );
io: (struct IOStdReq *) Pointer to the new IOStdReq
structure, or NULL if something went wrong.
msgp: (struct MsgPort *) Pointer to a MsgPort structure
with which the system can communicate with us.
Before your program terminates you must deallocate the request
block by calling the DeleteStdIO() function.
DeleteStdIO() deallocates a IOStdReq structure that has been
created by CreateStdIO(). Note that all allocated structures
must be deleted before the program may terminate.
Synopsis: DeleteStdIO( io );
io: (struct IOStdReq *) Pointer to the a IOStdReq
structure that should be deallocated.
Here is an example:
/* Declare a pointer to our I/O request block: */
struct IOStdReq *game_io_msg;
/* Allocate and initialize a new I/O request block: */
/* (It should use our new message port as reply port.) */
game_io_msg = CreateStdIO( game_msg_port );
/* Check if we have allocated the req. block successfully: */
if( !game_io_msg )
/* ERROR! Could not allocate new I/O request block! */
...
/* Deallocate I/O request block: */
DeleteStdIO( game_io_msg );
3.3.3 OPEN THE GAMEPORT DEVICE
Now you can open the Gameport Device with help of the
OpenDevice() function. When you open this device you must also
tell the system which port you want to monitor (unit 0 - the
"mouse port" or unit 1 - the "joystick" port). The function
will return 0 if everything is OK, or an error number if it
could not open the Gameport Device.
OpenDevice() will try to open the specified device. It will
return 0 if everything went OK, else an error number is
returned.
Synopsis: error = OpenDevice( name, unit, io, flags );
error: (long) OpenDevice() will return 0 if everything
went OK, or an error number if something went
wrong.
namne: (char *) Pointer to a string containing the name
of the device you want to open. The name of the
Gameport Device is "gameport.device".
unit: (long) Which unit should be used. The Gameport
Device can handle two ports:
unit 0 - the left "mouse port", port 1.
unit 1 - the right "joystick port", port 2.
io: (struct IORequest *) Pointer to an already
initialized IORequest or IOStdReq structure.
flags: (long) Additional information, set to 0.
Before your program terminates you have to close the Gameport
Device by calling the CloseDevice() function. CloseDevice()
tries to close a device that has previously been opened by an
OpenDevice() call.
Synopsis: CloseDevice( io );
io: (struct IORequest *) Pointer to an IORequest or
IOStdReq structure that has been used as parameter
in the OpenDevice() function call.
Here is an example:
/* Declare a boolean variable which will be TRUE if */
/* something when wrong, or FALSE if everything is OK: */
BOOL deviceerror;
/* Open the Game Port Device, use the right port (unit 1): */
deviceerror =
OpenDevice( "gameport.device", 1, game_io_msg, 0 );
/* Check if we have opened the device or not: */
if( deviceerror )
clean_up( "ERROR! Could not open the Game Port Device!" );
...
/* Close the Gameport Device: */
CloseDevice( game_io_msg );
3.3.4 CHECK IF SOME OTHER TASK IS ALREADY USING THE PORT
It is now important to check if some other task is already
monitoring the port, and if so we can not try to use it
ourself.
Set the io_Command field of the IOStdReq structure to
GPD_ASKCTYPE. This tells the system that you want to know what
type of controller, if any, is for the moment using the port.
We must now also give the structure (io_Data) a pointer to at
least one byte of free memory where the answer will be stored,
and tell the structure how much memory we gave it (io_Length).
We can now give our order to the Gameport Device by calling
the DoIO() function.
The DoIO() function will return as soon as the Gameport Device
has done our request. We should now be able to find the answer
at that memory position we specified, and if it is not equal to
GPCT_NOCONTROLLER some other task is already using the port.
Here is an example:
/* Put the answer in this variable: */
BYTE type;
/* Create message port, allocate IOStdReq structure and */
/* open the Gameport Device. */
/* We want to know what controller, if any, is used: */
game_io_msg->io_Command = GPD_ASKCTYPE;
/* The reply should only be one byte long: */
game_io_msg->io_Length = 1;
/* Where we want the data stored: */
game_io_msg->io_Data = (APTR) &type;
/* Do our request, and return when it is done: */
DoIO( game_io_msg );
/* Check if some other task is already using the gameport: */
if( type)
{
/* YES! Some other task is already using this port! */
/* Lets check what type of controller he is using: */
switch( type )
{
case GPCT_MOUSE:
printf( "A mouse is connected to the port!\n" );
break;
case GPCT_RELJOYSTICK:
printf( "A proportional joystick is connected to the port!\n" );
break;
case GPCT_ABSJOYSTICK:
printf( "A normal joystick is connected to the port!\n" );
break;
}
/* We may now NOT close the device! If we do it, the other */
/* task will then not be able to use the gameport device */
/* either! We should only deallocate the StdIOReq structure */
/* and close the message port! */
/* Deallocate I/O request block: */
DeleteStdIO( game_io_msg );
/* Close message port: */
DeletePort( game_msg_port );
exit( ERROR );
}
else
{
/* OK! No other task is using the port! */
}
3.3.5 SET TYPE OF CONTROLLER
We should now tell the Gameport Device what type of controller
(mouse or joystick) we want to monitor. To do this set the
io_Command field of the IOStdReq structure to GPD_SETCTYPE.
We must also give the field io_Data a pointer to at least one
byte of free memory where our request (mouse - GPD_MOUSE or
joystick- GPD_ABSJOYSTICK) is stored, and set the io_Length to
1 (we send 1 byte).
We can now give our order to the Gameport Device by calling
the DoIO() function.
/* We want to monitor mouse events: */
BYTE type = GPCT_MOUSE;
/* We want to set controller type: */
game_io_msg->io_Command = GPD_SETCTYPE;
/* The message is only one byte long: */
game_io_msg->io_Length = 1;
/* The data we want to send: */
game_io_msg->io_Data = (APTR) &type;
/* Do our request, and return when it is done: */
DoIO( game_io_msg );
When your program terminates it must set controller type back
to GPCT_NOCONTROLLER, before you close the Gameport Device! Do
as above except that you set type to GPCT_NOCONTROLLER.
/* We want to clear the port: */
BYTE type = GPCT_NOCONTROLLER;
/* We want to set controller type: */
game_io_msg->io_Command = GPD_SETCTYPE;
/* The message is only one byte long: */
game_io_msg->io_Length = 1;
/* The data we want to send: */
game_io_msg->io_Data = (APTR) &type;
/* Do our request, and return when it is done: */
DoIO( game_io_msg );
/* You may now close the Gameport Device, deallocate the */
/* IOStdReq structure and delete the message port. */
3.3.6 SET TRIGGER
No almost everything is prepared. The last thing you have to
do is to tell the Gameport Device when you want to receive
gameport events. There exist five different types of event
that may occur if you want, and they are:
1. A button was pressed. (GPTF_DOWNKEYS)
2. A button was released. (GPTF_UPKEYS)
3. Timeout. Nothing has happened within a specified timelimit.
4. Delta X movements. (Mouse or stick moved to the right/left.)
5. Delta Y movements. (Mouse or stick moved up/down.)
You set what type of trigger you want by initializing the
GamePortTrigger structure (defined in the headerfile "devices/
gameport.h"). The GamePortTrigger structure look like this:
struct GamePortTrigger
{
UWORD gpt_Keys;
UWORD gpt_Timeout;
UWORD gpt_XDelta;
UWORD gpt_YDelta;
};
gpt_Keys: If you want to trigger an event when a button is
pressed, set flag GPTF_DOWNKEYS. If you want to
trigger an event when a button is released, set
flag GPTF_UPKEYS. If you want to trigger an event
both when a button is pressed as well as when it
is released, set both flags with the binary
operator | in between, GPTF_DOWNKEYS|GPTF_UPKEYS.
gpt_Timeout: If this value is not zero, a timeout message will
be triggered if nothing has happened during the
specified timeperiod. The value is in vertical
blank units which occurs 60 times a second. So if
you want a message to be triggered after 30
seconds, set gpt_Timeout to 30 * 60 = 1800.
gpt_XDelta: How many x counts should occur before a message
is broadcasted. If you are monitoring a normal
joystick, set this value to 1.
gpt_YDelta: How many y counts should occur before a message
is broadcasted. If you are monitoring a normal
joystick, set this value to 1.
Fill this GamePortTrigger structure with your requirements,
and give the IOStdReq structure a pointer to it. Set the
io_Command field to GPD_SETTRIGGER (we want to tell the system
what should trigger an event). Finally do not forget that the
field io_Length should now be set to: sizeof( struct
GamePortTrigger ).
Here is an example:
/* This structure will be filled with our requirements: */
struct GamePortTrigger gpt;
/* Set our requirements: */
gpt.gpt_Keys = GPTF_DOWNKEYS|GPTF_UPKEYS; /* Up or down. */
gpt.gpt_Timeout = 600; /* 10 seconds. */
gpt.gpt_XDelta = 5; /* At least 5 */
gpt.gpt_YDelta = 5; /* counts. */
/* We want to set controller trigger: */
game_io_msg->io_Command = GPD_SETTRIGGER;
/* The message is sizeof(struct GamePortTrigger) bytes long: */
game_io_msg->io_Length = sizeof( gpt );
/* Pointer to the data we want to send: */
game_io_msg->io_Data = (APTR) &gpt;
/* Do our request and return when it is done: */
DoIO( game_io_msg );
3.3.7 PREPARE TO READ
The last thing we have to do is to prepare the Gameport Device
to send us messages each time a gameport event is triggered.
All information about the gameport event is automatically
stored in an InputEvent structure (defined in the headerfile
"devices/inputevent.h"), so what we have to do is to give
the Gameport Device a pointer to an InputEvent structure,
specify the size to sizeof( struct InputEvent), and set the
io_command to GPD_READEVENT.
Here is an example:
/* Store the information about the gameport event */
/* in this structure: */
struct InputEvent data;
/* We want to read gameport events: */
game_io_msg->io_Command = GPD_READEVENT;
/* The gameport event is sizeof(struct InputEvent) bytes long: */
game_io_msg->io_Length = sizeof( data );
/* Where we want the data to be placed: */
game_io_msg->io_Data = (APTR) &data;
/* Do not use quick io: */
game_io_msg->io_Flags = 0;
3.4 HOW TO MONITOR THE GAMEPORT
Once the Gameport Device has been properly prepared, you can
start monitoring the port. Each time you want to check the
port you send your request with help of the function SendIO().
/* Do our request, and return without delay: */
SendIO( game_io_msg );
You will now receive a message at our message port as soon as
a gameport event is triggered (the user has moved the joystick,
or a button has been pressed for example). If we do not want
to do anything while we are waiting for a gameport event, it
is best to call the WaitPort() function. It will put our task
to sleep so we do not waste any computer time. However, once
there appear a message at our port, our task is woken up.
/* Wait for a message to arrive at our message port. */
/* While we are waiting our task is put to sleep, */
/* which means that we will not waste any computer */
/* time. Zzz Zzz Zzz... */
WaitPort( game_msg_port );
Once we believe there is a message at our port, we can collect
it with help of the GetMsg() function. If we could not collect
a message, GetMsg() will return NULL. When we have collected
a message we know that the Gameport Device has filled our
InputEvent structure with some interesting information about
the gameport event.
It is important to remember that from that moment we send our
request with SendIO() until we collect a message with GetMsg()
we are not allowed to use the InputEvent structure. However,
once we have collected a message we may examine it or change
it as much as we want, until we send another request with
SendIO().
/* Try to Collect a message: */
if( GetMsg( game_msg_port ) )
{
/* If we have successfully collected a message, */
/* we may examine the InputEvent structure. */
}
PLEASE NOTE:
1. Before you can wait for a gameport event you must have
sent a gameport request by calling the SendIO()
function.
2. Before your program terminates you must have collected
every gameport request you have sent! If you close the
message port before you have answered all events,
something, not so nice, will happen.
3.4.1 THE INPUTEVENT STRUCTURE
As we said above, once you receive a gameport event you should
examine the InputEvent structure. The structure look like this:
(Defined in the headerfile "devices/inputevent.h".)
struct InputEvent
{
struct InputEvent *ie_NextEvent;
UBYTE ie_Class;
UBYTE ie_SubClass;
UWORD ie_Code;
UWORD ie_Qualifier;
union
{
struct
{
WORD ie_x;
WORD ie_y;
} ie_xy;
APTR ie_addr;
} ie_position;
struct timeval ie_TimeStamp;
};
/* These constants (together with many more) are also */
/* declared in the headerfile: */
#define ie_X ie_position.ie_xy.ie_x
#define ie_Y ie_position.ie_xy.ie_y
#define ie_EventAddress ie_position.ie_addr
ie_NextEvent: Pointer to the next InputEvent structure. (All
events are stored chronologically.)
ie_Class: What type of message it is. Not currently used
by the Gameport Device.
ie_SubClass: Extra field, sometimes used to more precisely
explain what has happened. Not currently used
by the Gameport Device.
ie_Code: This field tells us if a button has been pressed,
or released. (Remember that you will only
receive such messages if you have set the
gameport event triggers GPTF_DOWNKEYS and/or
GPTF_UPKEYS.)
If you are monitoring joystick events, and the
user presses the fire button, this field is set
to IECODE_LBUTTON. If the user later on releases
the fire button, this field is set to
IECODE_LBUTTON + IECODE_UP_PREFIX.
If you are monitoring mouse events, this field
can contain one of the following six different
types of messages:
IECODE_LBUTTON: Left mouse button pressed.
IECODE_MBUTTON: Middle mouse button pressed.(*)
IECODE_RBUTTON: Right mouse button pressed.
IECODE_LBUTTON+IECODE_UP_PREFIX: Left mouse button
was released.
IECODE_MBUTTON+IECODE_UP_PREFIX: Middle mouse button
was released. (*)
IECODE_RBUTTON+IECODE_UP_PREFIX: Right mouse button
was released.
[(*) Does not exist on the standard Amiga mouse.]
If no button was pressed or released, this field
is set to IECODE_NOBUTTON.
ie_Qualifier: Extra information for the code field. Not used by
the Gameport Device.
ie_x: Delta x movements.
If you are monitoring joystick events, 1 means
that the stick was move to the right, and -1
means that the stick was moved to the left.
If you are monitoring mouse events, this fields
tells you how many x counts the mouse has moved.
ie_y: Delta y movements.
If you are monitoring joystick events, 1 means
that the stick was move back, and -1 means that
the stick was moved forward.
If you are monitoring mouse events, this fields
tells you how many y counts the mouse has moved.
ie_addr: The address of the device that sent the message.
ie_TimeStamp: System timer.
3.4.1 COLLECT JOYSTICK EVENTS
Here is an example on how to collect joystick events:
("data" is a pointer to an initialized InputEvent structure.)
/* Store the direction of the stick and */
/* button position in these variables: */
WORD xdirection;
WORD ydirection;
UWORD code;
/* Collect data: */
xdirection = data->ie_X;
ydirection = data->ie_Y;
code = data->ie_Code;
/* Was the fire button pressed or released? */
if( code == IECODE_LBUTTON )
printf("Button pressed. ");
if( code == IECODE_LBUTTON + IECODE_UP_PREFIX )
printf("Button released. ");
/* What is the position of the stick: */
switch(ydirection)
{
case -1:
printf( "Forward" );
break;
case 1:
printf( "Back" );
break;
}
switch(xdirection)
{
case -1:
printf( "Left" );
break;
case 1:
printf( "Right" );
break;
}
3.4.2 COLLECT MOUSE EVENTS
Here is an example on how to collect mouse events:
("data" is a pointer to an initialized InputEvent structure.)
WORD x;
WORD y;
UWORD code;
/* Collect data: */
x = data->ie_X;
y = data->ie_Y;
code = data->ie_Code;
/* Check if an mouse button has been pressed/released: */
switch( code )
{
case IECODE_LBUTTON:
printf( "Left mouse button pressed" );
break;
case IECODE_MBUTTON:
printf( "Middle mouse button pressed" );
break;
case IECODE_RBUTTON:
printf( "Right mouse button pressed" );
break;
case IECODE_LBUTTON + IECODE_UP_PREFIX:
printf( "Left mouse button released" );
break;
case IECODE_MBUTTON + IECODE_UP_PREFIX:
printf( "Middle mouse button released" );
break;
case IECODE_RBUTTON + IECODE_UP_PREFIX:
printf( "Right mouse button released" );
break;
case IECODE_NOBUTTON:
printf( "No buttons pressed/released" );
/* This meant that you have either received a timeout */
/* message, or the mouse has been moved. */
break;
}
/* Check delta movement: */
printf( "Delta X: %4d Delta Y: %4d\n", x, y );
3.5 FUNCTIONS
Note that several of these functions are rather complicated,
and have not been fully explained in this chapter. For more
information se chapter XXXXX. Here is at least a short
description of what they are doing, and how they should be
used.
CreatePort()
This function allocates and initializes a MsgPort structure.
If you give it a string as first parameter it will also make
the port public. If CreatePort() of some reason could not
create a message port it returns NULL, otherwise if everything
is OK it returns a pointer to the new MsgPort structure.
Note that a port that has been created by calling
CreatePort(), must be deallocated before your program
terminates. The easiest way to deallocate a message
port is to use the DeletePort() function.
Synopsis: msgp = CreatePort( name, pri );
msgp: (struct MsgPort *) Pointer to the new MsgPort
structure, or NULL if something went wrong.
name: (char *) Pointer to a string containing the name
of the message port, or NULL. If it is a string
the port will be made public (so other tasks can
find it) else only our task can use it.
msgp: (struct MsgPort *) Pointer to the MsgPort structure
that should be deallocated.
pri: (BYTE) This message port's priority. Usually set
to 0 - normal priority.
DeletePort()
This function deletes a message port. Every message port that
has been allocated by CreatePort() must be deleted before the
program terminates.
Synopsis: DeletePort( msgp );
msgp: (struct MsgPort *) Pointer to the MsgPort structure,
that should be deallocated.
CreateStdIO()
This function allocates and initializes a new IOStdReq
structure. As only parameter you give it a pointer to a
message port that will be used by the system to communicate
with you. If the function succeeds, it returns a pointer to
the new IoStdReq structure, else NULL which means something
went wrong.
Note that a IOStdReq structure that has been allocated by
CreateStdIO(), must be deallocated before the program
terminates. To do this, use the function DeleteStdIO().
Synopsis: io = CreateStdIO( msgp );
io: (struct IOStdReq *) Pointer to the new IOStdReq
structure, or NULL if something went wrong.
msgp: (struct MsgPort *) Pointer to a MsgPort structure
with which the system can communicate with us.
DeleteStdIO()
This function deallocates a IOStdReq structure that has
been created by CreateStdIO(). Note that all allocated
structures must be deleted before the program may
terminate.
Synopsis: DeleteStdIO( io );
io: (struct IOStdReq *) Pointer to the a IOStdReq
structure that should be deallocated.
OpenDevice()
This function will try to open the specified device. It will
return 0 if everything went OK, else an error number is
returned.
Note that if you have opened a device, your program must
close it before it terminates. However, if you have opened
a device that is already being used by some other task
you should not close it. Close a device by calling the
CloseDevice() function.
Synopsis: error = OpenDevice( name, unit, io, flags );
error: (long) OpenDevice() will return 0 if everything
went OK, or an error number if something went
wrong.
namne: (char *) Pointer to a string containing the name
of the device you want to open. The name of the
Gameport Device is "gameport.device".
unit: (long) Which unit should be used. The Gameport
Device can handle two ports:
unit 0 - the left "mouse port", port 1.
unit 1 - the right "joystick port", port 2.
io: (struct IORequest *) Pointer to an already
initialized IORequest or IOStdReq structure.
flags: (long) Additional information, set to 0.
CloseDevice()
This function closes a device that has previously been opened
by an OpenDevice() call. Note that if you have opened a
device, your program must close it before it terminates.
However, if you have opened a device that is already being
used by some other task you should not close it.
Synopsis: CloseDevice( io );
io: (struct IORequest *) Pointer to an IORequest or
IOStdReq structure that has been used as parameter
in the OpenDevice() function call.
3.6 EXAMPLES
Example1
This example demonstrates how to open the Gameport Device,
and monitor Joystick events. While we are waiting we
put our task to sleep so we do not waste any computer time.
Example2
Same as example 1, but instead of putting the task to sleep
while we are waiting for something to happen, we constantly
try to receive joystick events. This should for example be
used in games. I am sure that you so not want that all aliens
should stop attacking the world just because the user has
not moved the stick.
Example3
This example demonstrates how to open the Gameport Device,
and monitor mouse events. While we are waiting we put our
task to sleep so we do not waste any computer time.
Example4
Same as example 3, but instead of putting the task to sleep
while we are waiting for something to happen, we constantly
try to receive mouse events.